gusucode.com > VC 达内MFC例子集源码-源码程序 > VC 达内MFC例子集源码-源码程序/code/20101227/day01.txt
MFC应用程序编程 一 MFC的发展 VC 1.0->VC 5.0->VC 6.0->VC2008 SP1)->VS2010 二 MFC基础 1 MFC 微软基础类库 采用类的方式,将Win32 API等进行封装, 形成的库. 2 MFC相关的头文件 afx.h (application framework, X) afxwin.h (类似于windows.h) afxext.h MFC扩展头文件 ... 三 MFC应用程序 1 MFC的控制台程序 1.1 包含afx系列的头文件 1.2 CWinApp theApp - MFC的应用程序类 封装了应用程序的启动过程. 1.3 AfxWinInit MFC初始化函数 将应用程序的信息初始化. 2 MFC的动态库和静态库 2.1 静态库 - 增加了MFC的支持 2.2 动态库 2.2.1 MFC规则DLL 2.2.1.1 使用MFC静态库的规则DLL 2.2.1.2 使用MFC动态库的规则DLL 2.2.2 MFC扩展DLL 2.3 不同 2.3.1 MFC相关的afx头文件 2.3.2 包含一个继承CWinApp类, 并且 声明了该类的全局变量. 3 MFC应用程序 3.1 单文档视图应用程序 3.1.1 包含一个继承CWinApp类 3.1.2 CMainFrame类 3.1.3 CView的一个子类 3.1.4 CDocument的一个子类 3.2 多文档视图应用程序 3.2.1 包含一个继承CWinApp类 3.2.2 CMainFrame类 3.2.3 CView的一个子类 3.2.4 CDocument的一个子类 3.2.5 CChildFrame 子框架窗口 3.3 对话框应用程序 3.3.1 包含一个继承CWinApp类 3.3.2 对话框类 四 MFC中的类 1 CObject类 MFC类的基础,大部分MFC类都是它的子类. CObject封装了MFC的基础的机制 1.1 new和Delete 1.2 Assert 1.3 运行式信息 1.4 动态创建 1.5 序列化 2 应用程序框架 应用程序启动相关信息,以及MFC消息映射 机制。 3 窗口支持类 封装了窗口操作的API,各种控件及窗口的 框架. 4 绘图类 提供了绘图API的封装,以及相关的GDI设备 封装. 5 MFC的集合类 提供了数组、链表、映射的数据结构的操作. 6 数据库支持类 ODBC支持类和DAO的支持类。 DAO的类已作废. 7 同步类 临界区/事件/互斥/信号量的封装 8 Socket类 封装了socket的编程. 9 常用数据结构 CString CRect CPoint等. 五 第一个MFC程序 1 环境设置 1.1 修改头文件 1.2 在Setting中增加MFC库支持 2 增加应用程序类CWinApp 2.1 添加CWinApp的子类CMyApp 2.2 添加InitInstance函数 是在程序启动过程中,会被调用,我们可以 在这个函数中,创建窗口或者各种初始化 操作. 2.3 添加CMyApp的全局变量 3 窗口 3.1 添加CFrameWnd的子类CMyFrameWnd 3.2 在App的InitInstance函数定义窗口 对象 3.3 创建窗口(Create)并显示(ShowWindow) 3.4 将窗口设置成App的主窗口 m_pMainWnd = pWnd; 3.5 在CMyFrameWnd中添加窗口处理函数 WindowProc,在WindowProc中处理消息 六 MFC应用程序的启动 MFC应用程序与Win32程序一样,都需要程序 的入口函数. 1 CWinApp 应用程序类,封装了应用程序的相关信息, 可以提供初始化 消息循环等处理. CWinApp的构造函数: 1.1 将this指针保存到ThreadState中. m_pCurrentWinThread = this 1.2 将this指针保存到ModuleState中 m_pCurrentWinApp = this 1.3 各种的成员变量的初始化 2 程序的入口函数 2.1 WinMain函数,与Win32程序一致. 2.2 在WinMain函数中,调用了AfxWinMain 函数. 2.3 AfxWinMain函数 2.3.1 调用AfxWinInit初始化应用程序 2.3.2 调用CWinApp的InitApplication 初始MFC内部数据 2.3.3 调用CWinThread的InitInstance 函数做初始化操作 2.3.4 调用CWinThread的Run函数进行 消息循环 2.3.5 调用AfxWinTerm函数做退出处理. 3 程序的启动 3.1 CWinApp在构造过程中, 将自己的this 指针分别保存到全局变量中. 3.2 在AfxWinMain执行中,首先从全局变量 中将保存CWinApp的地址获取到. 3.3 调用CWinApp的InitInstance函数,进行 初始化.我们在InitInstance函数中,创建 窗口等初始化操作. 3.4 调用Run函数,进行消息循环. 七 窗口创建及窗口处理函数 1 窗口创建 1.1 窗口的参数初始化,包括窗口类.风格 窗口处理函数等信息. 注意: 将DefWindowProc注册成窗口处理函数. 1.2 设置 创建HOOK (钩子) 当窗口创建的时候,调用这个HOOK函数. Wnd -> HOOK -> WndProc 1.3 创建窗口 CreateWindowEx 1.4 卸载创建HOOK 将HOOK程序从当前程序中移除 2 HOOK(钩子)程序 2.1 使用AfxGetAfxWndProc函数获取了 一个WNDPROC函数指针, 也就是 AfxWndProc(AfxWndProcBase)函数 地址. 2.2 将这个WNDPROC函数设置成当前窗口的 处理函数 2.3 将窗口句柄和窗口类的指针保存到 MFC的映射数据中.(afxMapHWND函数) 3 AfxWndProc(Base)窗口处理函数 3.1 根据窗口句柄获取了相对应的窗口 的CWnd *类型的指针,从映射数据中 根据窗口句柄查找CWnd *指针. (afxMapHWND函数) 3.2 调用AfxCallWndProc函数 3.3 在AfxCallWndProc函数中,调用CWnd 的WindowProc函数 注意: 在MFC程序当中,所有窗口处理都是 使用一个函数. 4 窗口的创建及处理过程 4.1 将DefWindowProc函数注册成当前 窗口的处理函数 4.2 设置钩子函数 4.3 创建窗口,并执行钩子函数 4.4 将窗口类指针和窗口句柄的对应关系 保存. 4.5 在钩子函数将AfxWndProc(Base)函数 设置当前窗口的窗口处理函数 4.6 在AfxWndProc(Base)收到窗口消息, 从窗口对应关系中,查询相应的窗 口类指针. 4.7 调用窗口类WindowProc函数处理消息 八 消息映射 1 消息映射添加 1.1 在FrameWnd添加消息宏定义 DECLARE_MESSAGE_MAP 1.2 添加消息宏实现 1.3 添加消息处理函数 1.4 添加消息和处理函数的对应 2 消息宏的实现 2.1 数据类型 2.1.1 AFX_MSGMAP_ENTRY 是用于保存 消息ID与对应函数指针,及相关的信息 struct AFX_MSGMAP_ENTRY { UINT nMessage; //消息ID UINT nCode;//通知代码 UINT nID; //控件的ID UINT nLastID;//控件的ID范围的最后 UINT nSig;//操作类型或pfn函数类型 AFX_PMSG pfn;//消息处理函数的函数指针 }; 2.1.2 AFX_MSGMAP 用于保存GetBaseMap 的函数地址及AFX_MSGMAP_ENTRY数组的 地址. struct AFX_MSGMAP { const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)(); //函数指针 const AFX_MSGMAP_ENTRY* lpEntries; //AFX_MSGMAP_ENTRY类型指针 }; 2.2 代码 class CMsgFrame : public CFrameWnd { private: static const AFX_MSGMAP_ENTRY _messageEntries[]; protected: static AFX_DATA const AFX_MSGMAP messageMap; static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); virtual const AFX_MSGMAP* GetMessageMap() const; } const AFX_MSGMAP* PASCAL CMsgFrame::_GetBaseMessageMap() { return &CFrameWnd::messageMap; } const AFX_MSGMAP* CMsgFrame::GetMessageMap() const { return &CMsgFrame::messageMap; } AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CMsgFrame::messageMap = { &CMsgFrame::_GetBaseMessageMap, &CMsgFrame::_messageEntries[0] }; AFX_COMDAT const AFX_MSGMAP_ENTRY CMsgFrame::_messageEntries[] = { { WM_PAINT, 0, 0, 0, AfxSig_lwl,(AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&OnPaint }, {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };